#include "GameObject.h"
#include "Game.h"
#include "Factory.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"


#include <vector>

GameObject::GameObject() : m_id(0), mp_collShape(nullptr), m_mass(0)
{ 
	mp_motionState = (nullptr);
	m_localInertia = btVector3(0,0,0);
	
	//Bullet collision flags
	ballCollidesWith = COL_TERRAIN | COL_CATAPULT | COL_TARGET;
	terrainCollidesWith = COL_CATAPULT | COL_TARGET | COL_BALL;
	catapultCollidesWith = COL_BALL | COL_TARGET;
	targetCollidesWith = COL_BALL | COL_TERRAIN | COL_TARGET;

}


bool GameObject::Load(File* const f)
{
	return true;
}

void GameObject::SetId(int newId)
{
	m_id = newId;
}

void GameObject::MakeDynamicCollisionShapeFromMesh(ObjMesh* mesh, float mass)
{
	std::vector<Vec3f> verts = *mesh->GetCoords();
	Faces* faces = mesh->GetFaces();

	btConvexHullShape* convexHull = new btConvexHullShape();

	Faces::iterator it = faces->begin();
	//std::vector<Vec3f>::iterator it = verts.begin();

	Vec3f tempPoint;

	for ( ; it != faces->end(); ++it)
	{
		tempPoint = verts[(*it).m_pointIndex[0]];
		convexHull->addPoint(btVector3(tempPoint.X, tempPoint.Y, tempPoint.Z));

		tempPoint = verts[(*it).m_pointIndex[1]];
		convexHull->addPoint(btVector3(tempPoint.X, tempPoint.Y, tempPoint.Z));

		tempPoint = verts[(*it).m_pointIndex[2]];
		convexHull->addPoint(btVector3(tempPoint.X, tempPoint.Y, tempPoint.Z));
	}

	mp_collShape = convexHull;
	CreateCollisionShape(mp_collShape, mass);

}

void GameObject::MakeStaticCollisionShapeFromMesh(ObjMesh* mesh, float mass)
{
	
	std::vector<Vec3f> verts = *mesh->GetCoords();
	Faces* faces = mesh->GetFaces();

	btTriangleMesh* triMesh = new btTriangleMesh;

	//std::vector<Vec3f>::iterator it = verts.begin();
	Faces::iterator it = faces->begin();

	btVector3 a, b, c;
	int i = faces->size();
	
	Vec3f tempPoint;
	for ( ; it != faces->end(); ++it)
	{
		tempPoint = verts[(*it).m_pointIndex[0]];
		a = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	
		
		tempPoint = verts[(*it).m_pointIndex[1]];
		b = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	

		tempPoint = verts[(*it).m_pointIndex[2]];
		c = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	

		triMesh->addTriangle(a,b,c, false);
	}

	bool useQuantizedAabbCompression = true;

	btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
	
	CreateCollisionShape(new btBvhTriangleMeshShape(triMesh,true, true), mass);
}


void GameObject::MakeStaticCollisionShapeFromMesh(ObjMesh* mesh, float mass, int collGroup, int collisionMask)
{
	
	std::vector<Vec3f> verts = *mesh->GetCoords();
	Faces* faces = mesh->GetFaces();

	btTriangleMesh* triMesh = new btTriangleMesh;

	//std::vector<Vec3f>::iterator it = verts.begin();
	Faces::iterator it = faces->begin();

	btVector3 a, b, c;
	int i = faces->size();
	
	Vec3f tempPoint;
	for ( ; it != faces->end(); ++it)
	{
		tempPoint = verts[(*it).m_pointIndex[0]];
		a = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	
		
		tempPoint = verts[(*it).m_pointIndex[1]];
		b = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	

		tempPoint = verts[(*it).m_pointIndex[2]];
		c = btVector3(tempPoint.X,tempPoint.Y,tempPoint.Z);	

		triMesh->addTriangle(a,b,c, false);
	}

	bool useQuantizedAabbCompression = true;

	btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
	
	CreateCollisionShape(new btBvhTriangleMeshShape(triMesh,true, true), mass, collGroup, collisionMask);
}

void GameObject::CreateCollisionShape(btCollisionShape* shape, float mass) 
{ 
	mp_collShape = shape;

	m_mass = mass;
	
	if (m_mass != 0.0f)
	{
		m_isDynamic = true;
		mp_collShape->calculateLocalInertia(m_mass, m_localInertia);
	}
	
	btTransform trans;
	trans.setIdentity();
	mp_motionState = new btDefaultMotionState(trans);
	btRigidBody::btRigidBodyConstructionInfo rbInfo(m_mass, mp_motionState, shape, m_localInertia);
	mp_rigidBody = new btRigidBody(rbInfo);
	assert(mp_rigidBody);

	TheGame::Instance()->AddCollisionShape(shape);
	
	TheGame::Instance()->GetDynWorld()->addRigidBody(mp_rigidBody);

	mp_rigidBody->setUserPointer(this);

}

void GameObject::CreateCollisionShape(btCollisionShape* shape, float mass, int collGroup, int collisionMask) 
{ 
	mp_collShape = shape;

	m_mass = mass;
	
	if (m_mass != 0.0f)
	{
		m_isDynamic = true;
		mp_collShape->calculateLocalInertia(m_mass, m_localInertia);
	}
	
	btTransform trans;
	trans.setIdentity();
	mp_motionState = new btDefaultMotionState(trans);
	btRigidBody::btRigidBodyConstructionInfo rbInfo(m_mass, mp_motionState, shape, m_localInertia);
	mp_rigidBody = new btRigidBody(rbInfo);
	assert(mp_rigidBody);

	TheGame::Instance()->AddCollisionShape(shape);
	
	TheGame::Instance()->GetDynWorld()->addRigidBody(mp_rigidBody, collGroup, collisionMask );

	mp_rigidBody->setUserPointer(this);

}



btDefaultMotionState* GameObject::GetMotionState()
{
	return mp_motionState;
}
btRigidBody* GameObject::GetRigidBody()
{
	return mp_rigidBody;
}

